#include "shellCmd.h"

#ifdef AW_SHELL

extern SHELL_CommandTypeDef shellCmdStructArray[SHELL_CMD_LIST_COUNT];
/*******************************************************************************
 *@function  shellShowCommandList
 *@brief     shell????help????,????????shell??
 *@param     None
 *@retval    None
 *@author    Letter
 *******************************************************************************/
int shellShowCmdList(uint32_t argc, const char *argv[])
{
	int32_t spaceLength;

	shellDisplay("COMMAND                 FUNCTION\r\n");
	shellDisplay("--------------------------------\r\n");

	for (int8_t i = 0;
			i < sizeof(shellCmdStructArray) / sizeof(*shellCmdStructArray); i++)
	{
		spaceLength = 30 - (int32_t) shellDisplay(shellCmdStructArray[i].name);
		spaceLength = (spaceLength > 0) ? spaceLength : 4;
		do
		{
			shellDisplay(" ");
		} while (--spaceLength);
		//shellDisplay("\t");
		shellDisplay(shellCmdStructArray[i].describe);
		shellDisplay("\r\n");
	}
	return 0;
}

/*******************************************************************************
 *@function  shellLetter
 *@brief     shell??
 *@param     None
 *@retval    None
 *@author    Letter
 *******************************************************************************/
int shellAbout(uint32_t argc, const char *argv[])
{
	shellDisplay("alwhales shell "SHELL_VERSION"\r\n");
	shellDisplay(
			"(C) Copyright 2018 AlwhalesTech. Co.,LTD. All Right Reserved\r\n");
	return 0;
}

/*******************************************************************************
 *@function  shellRebot
 *@brief     ????
 *@param     None
 *@retval    None
 *@author    Letter
 *******************************************************************************/
int shellReboot(uint32_t argc, const char *argv[])
{
	shellDisplay("system rebooting\r\n");
	__set_FAULTMASK(1);
	NVIC_SystemReset();
	return 0;
}

#if SHELL_MODE==SHELL_MODE_TERMINAL
/*******************************************************************************
 *@function  shellClear
 *@brief     ?????
 *@param     None
 *@retval    None
 *@author    Letter
 *******************************************************************************/
int shellClear(uint32_t argc, const char *argv[])
{
	shellDisplay("\033[2J\033[1H");
	return 0;
}
#endif

//#if SHELL_USE_PARAMETER == 1
/*******************************************************************************
 *@function  shellParaTest
 *@brief     ????????
 *@param     argc        ????
 *           argv        ??
 *@retval    None
 *@author    Letter
 *******************************************************************************/
int shellParaTest(uint32_t argc, const char *argv[])
{
	shellDisplayByte((uint8_t)(argc + '0'));
	shellDisplay(" parameter(s)\r\n");
	if (argc == 1)
	{
		return 0;

	}
	while (--argc > 0)
	{
		shellDisplay(*++argv);
		shellDisplay("\r\n");
	}
	return 0;
}

/**
 * Get 96 bits UUID of MCU.
 */
int shellCmd_Get_CPU_UUID(uint32_t argc, const char *argv[])
{
	uint32_t ChipUniqueID[3];
	char stringTemp[50];

	ChipUniqueID[2] = *(volatile uint32_t*) (UID_BASE);
	ChipUniqueID[1] = *(volatile uint32_t*) (UID_BASE + 4U);
	ChipUniqueID[0] = *(volatile uint32_t*) (UID_BASE + 8U);

	if (argc < 2)
	{
		for (int i = 0; i < 3; i++)
		{
			sprintf(stringTemp, "$aw:uuid@i:0x%X$", ChipUniqueID[i]);
			shellDisplay(stringTemp);
		}
	}
	else
	{
		argv++;
		//		channel=(*argv)[0]-'0';
		if (strcmp( *argv, (const char*) "0") == 0)
		{
			sprintf(stringTemp, "$aw:uuid@0:0x%X$", ChipUniqueID[0]);
		}
		else if (strcmp( *argv,(const char*) "1") == 0)
		{
			sprintf(stringTemp, "$aw:uuid@1:0x%X$", ChipUniqueID[1]);
		}
		else if (strcmp( *argv,(const char*) "2") == 0)
		{
			sprintf(stringTemp, (const char*) "$aw:uuid@2:0x%X$", ChipUniqueID[2]);
		}
		else
		{
			return -1;
		}
		shellDisplay(stringTemp);
	}
	return 0;
}

int shellCmd_PWM_Cmd(uint32_t argc, const char *argv[])
{
	return 0;
}

int shellCmd_PWM_SetDutyCycle(uint32_t argc, const char *argv[])
{
	return 0;
}

int shellCmd_GPIO_SetValue(uint32_t argc, const char *argv[])
{
	return 0;
}

int shellCmd_ADC_GetValue(uint32_t argc, const char *argv[])
{
	return 0;
}

/*
 * Operate basic timer, default 1KHz update frequency.
 * -t: timer type (1~4)
 * -f: base count frequency (2k~72MHz)
 * -p: count period
 * -c: cmd (0~1)
 */
int shellCmd_OptBasicTimer(uint32_t argc, const char *argv[])
{
//	int opt = 0;
//	uint32_t baseFreq;
//	TIM_TypeDef *TIMx = TIM2;
//	uint16_t TIMx_Prescaler = 72;
//	uint16_t TIMx_Period = 1000;
//	uint16_t IsEnable = 0;
//	optind = 0;
//	optarg = 0;
//	opterr = 0;
//	optopt = 0;
//	while ((opt = getopt(argc,(char * const *) argv,(const char*) "t:f:p:c:")) != -1)
//	{
//		switch (opt)
//		{
//		case 't':
//			switch (atoi(optarg))
//			{
//			case 1:
//				TIMx = TIM1;
//				break;
//			case 2:
//				TIMx = TIM2;
//				break;
//			case 3:
//				TIMx = TIM3;
//				break;
//			case 4:
//				TIMx = TIM4;
//				break;
//			default:
//				return -1;
//			}
//			break;
//		case 'f':
//			baseFreq = atoi(optarg);
//			TIMx_Prescaler = SystemCoreClock / baseFreq - 1;
//			TIMx->PSC = TIMx_Prescaler;
//			break;
//		case 'p':
//			TIMx_Period = atoi(optarg) - 1;
//			TIMx->ARR = TIMx_Period;
//			break;
//		case 'c':
//			if (atoi(optarg) != 0)
//				IsEnable = 1;
//			else
//				IsEnable = 0;
//			TIM_Cmd(TIMx, IsEnable);
//			break;
//		default:
//			return -1;
//		}
//	}
	return 0;
}

/*
 * Operate global variable SensorData array.(default read)
 * -w write data
 * -i: index
 * -v: value
 */
int shellCmd_OptSensorData(uint32_t argc, const char *argv[])
{
//	int opt = 0;
//	int direction = 0;
//	int index = 0;
//	float value = 0;
//	char strTemp[50];
//
//	optind = 0;
//	optarg = 0;
//	opterr = 0;
//	optopt = 0;
//	while ((opt = getopt(argc, (char * const *)argv, (const char *)"awi:v:")) != -1)
//	{
//		switch (opt)
//		{
//		case 'a':
//			for (uint8_t i = 0; i < SENSOR_DATA_COUNT; i++)
//			{
//				sprintf(strTemp, (const char *) "$aw:sensor@%d:%f$", i, SensorData[i].value);
//				shellDisplay(strTemp);
//			}
//		case 'w':
//			direction = 1;	//write
//			break;
//		case 'i':
//			index = atoi(optarg);
//			break;
//		case 'v':
//			value = atof(optarg);
//			break;
//		default:
//			return -1;
//		}
//	}
//
//	if (direction != 0)
//	{
//		SensorData[index].value = value;
//	}
//	else
//	{
//		sprintf(strTemp, (const char *)"$aw:sensor@%d:%f$", index, SensorData[index].value);
//		shellDisplay(strTemp);
//	}
	return 0;
}

/*
 * Operate global variable ConfigData array.(default read)
 * -w write data
 * -i: index
 * -v: value
 */
int shellCmd_OptConfigData(uint32_t argc, const char *argv[])
{
//	int opt = 0;
//	int direction = 0;
//	int index = 0;
//	float value = 0;
//	char strTemp[50];
//
//	optind = 0;
//	optarg = 0;
//	opterr = 0;
//	optopt = 0;
//	while ((opt = getopt(argc,(char * const *) argv,(const char *) "awi:v:")) != -1)
//	{
//		switch (opt)
//		{
//		case 'a':
//			for (uint8_t i = 0; i < CONFIG_DATA_COUNT; i++)
//			{
//				sprintf(strTemp,(const char *) "$aw:config@%d:%f$", i, ConfigData[i].value);
//				shellDisplay(strTemp);
//			}
//		case 'w':
//			direction = 1;	//write
//			break;
//		case 'i':
//			index = atoi(optarg);
//			break;
//		case 'v':
//			value = atof(optarg);
//			break;
//		default:
//			return -1;
//		}
//	}
//
//	if (direction != 0)
//	{
//		ConfigData[index].value = value;
//	}
//	else
//	{
//		sprintf(strTemp, (const char *)"$aw:config@%d:%f$", index, ConfigData[index].value);
//		shellDisplay(strTemp);
//	}
	return 0;
}
/*
 * Operate global storable variable StorableData_Struct array.(default read)
 * -a read all data
 * -w write data
 * -i: index
 * -v: value
 */
int shellCmd_OptStorableData_Value(uint32_t argc, const char *argv[])
{
//	int opt = 0;
//	int direction = 0;
//	int index = 0;
//	float value;
//	char strTemp[50];
//
//	optind = 0;
//	optarg = 0;
//	opterr = 0;
//	optopt = 0;
//	while ((opt = getopt(argc, (char * const *)argv, (const char *)"awi:v:")) != -1)
//	{
//		switch (opt)
//		{
//		case 'a':
//			for (uint8_t i = 0; i < STORABLE_DATA_COUNT; i++)
//			{
//				sprintf(strTemp, "$aw:storable@%d:%f$", i,
//						StorableData[i].value.toFloat);
//				shellDisplay(strTemp);
//				delay_ms(10);
//			}
//		case 'w':
//			direction = 1;	//write
//			break;
//		case 'i':
//			index = atoi(optarg);
//			break;
//		case 'v':
//			value = atof(optarg);
//			break;
//		default:
//			return -1;
//		}
//	}
//	if (direction != 0)
//	{
//		StorableData[index].value.toFloat = value;
//	}
//	else
//	{
//		sprintf(strTemp, "$aw:storable@%d:%.3f$", index,
//				StorableData[index].value.toFloat);
//		shellDisplay(strTemp);
//	}
	return 0;
}

/*
 * Save global storable variable StorableData_Struct array to eeprom.(default single variable and save value)
 * -a all variable
 * -d save default value
 * -i: index
 */
int shellCmd_SaveStorableData(uint32_t argc, const char *argv[])
{
//	int opt = 0;
//	int index = 0;
//	int all = 0;
//	int isDefaultValue = 0;
////	char strTemp[50];
//
//	optind = 0;
//	optarg = 0;
//	opterr = 0;
//	optopt = 0;
//	while ((opt = getopt(argc, (char* const*) argv, (const char*)"adi:")) != -1)
//	{
//		switch (opt)
//		{
//		case 'a':
//			all = 1;
//			break;
//		case 'd':
//			isDefaultValue = 1;
//			break;
//		case 'i':
//			index = atoi(optarg);
//			break;
//		default:
//			return -1;
//		}
//	}
//	if (isDefaultValue != 0)
//	{
//		if (all != 0)
//		{
//			StorableData_SaveAllDefaultValue();
//		}
//		else
//		{
//			StorableData_SaveDefaultValue((const EepromData_typedef*) &StorableData[index]);
//		}
//	}
//	else
//	{
//		if (all != 0)
//		{
//			StorableData_SaveAllValue();
//		}
//		else
//		{
//			StorableData_SaveValue((EepromData_typedef*) &StorableData[index]);
//		}
//	}
	return 0;
}

/*
 * Load value of global storable variable StorableData_Struct array from eeprom or default value.(default single variable and load from default value)
 * -a all variable
 * -e load value from eeprom
 * -i: index
 */
int shellCmd_LoadStorableData(uint32_t argc, const char *argv[])
{
//	int opt = 0;
//	int index = 0;
//	int all = 0;
//	int isFromEeprom = 0;
////	char strTemp[50];
//
//	optind = 0;
//	optarg = 0;
//	opterr = 0;
//	optopt = 0;
//	while ((opt = getopt(argc, (char * const*)argv, (const char*)"aei:")) != -1)
//	{
//		switch (opt)
//		{
//		case 'a':
//			all = 1;
//			break;
//		case 'e':
//			isFromEeprom = 1;
//			break;
//		case 'i':
//			index = atoi(optarg);
//			break;
//		default:
//			return -1;
//		}
//	}
//	if (isFromEeprom != 0)
//	{
//		if (all != 0)
//		{
//			StorableData_LoadAllValueFromEEPROM();
//		}
//		else
//		{
//			StorableData_LoadValueFromEEPROM((EepromData_typedef *) &StorableData[index]);
//		}
//	}
//	else
//	{
//		if (all != 0)
//		{
//			StorableData_ResetAllValue();
//		}
//		else
//		{
//			StorableData_ResetValue((EepromData_typedef *)&StorableData[index]);
//		}
//	}
	return 0;
}
#endif
